<template>
  <view class="image-uploader">
    <!-- 多图预览模式 -->
    <view class="image-list" v-if="displayValues.length > 0">
      <view class="image-preview" v-for="(item, index) in displayValues" :key="index">
        <image :src="cloudIdToUrl(item)" mode="aspectFit" class="preview-image" @click="previewImage(index)"></image>
        <view class="image-actions">
          <uni-icons type="close" size="24" color="#fff" @click="removeImage(index)"></uni-icons>
        </view>
      </view>
      <view v-if="displayValues.length < maxCount" class="upload-btn" @click="chooseImage">
        <uni-icons type="plusempty" size="32" color="#999"></uni-icons>
        <text class="upload-text">添加图片</text>
      </view>
    </view>
    <!-- 单图上传模式（当没有图片时） -->
    <view v-else class="upload-btn" @click="chooseImage">
      <uni-icons type="plusempty" size="32" color="#999"></uni-icons>
      <text class="upload-text">选择图片</text>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { cloudIdToUrl, urlToCloudId } from '@/utils/common.js'
const wallpaperObj = uniCloud.importObject('iss-wallpaper')

const props = defineProps({
  modelValue: {
    type: [String, Array],
    default: () => []
  },
  // 上传路径前缀，如 'wallpaper/category'
  uploadPath: {
    type: String,
    default: 'common'
  },
  // 压缩质量 (0-100)
  quality: {
    type: Number,
    default: 80
  },
  // 最大宽度/高度
  maxSize: {
    type: Number,
    default: 1024
  },
  // 最大上传数量
  maxCount: {
    type: Number,
    default: 1
  }
})

const emit = defineEmits([
  'update:modelValue', 
  'upload-success', 
  'upload-error', 
  'remove',
  'temp-file-change'
])

// 临时文件数组
const tempImageFiles = ref([])
// 显示的值数组（可能是临时路径或云存储ID）
const displayValues = ref([])
// 存储云图片ID数组
const _ids = ref([])

// 初始化显示值
const initDisplayValues = () => {
  if (Array.isArray(props.modelValue)) {
    displayValues.value = [...props.modelValue]
  } else if (props.modelValue) {
    displayValues.value = [props.modelValue]
  } else {
    displayValues.value = []
  }
}


// 预览图片
const previewImage = (index) => {
  const urls = displayValues.value.map(item => 
    item.startsWith('cloud://') || item.startsWith('qiniu://') 
      ? cloudIdToUrl(item) 
      : item
  )
  uni.previewImage({
    current: urls[index],
    urls: urls
  })
}

// 选择图片
const chooseImage = () => {
  const count = props.maxCount - displayValues.value.length
  uni.chooseImage({
    count: count,
    sizeType: ['compressed'],
    sourceType: ['album', 'camera'],
    success: (res) => {
      tempImageFiles.value = [...tempImageFiles.value, ...res.tempFiles]
      displayValues.value = [...displayValues.value, ...res.tempFilePaths]
      updateModelValue()
      emit('temp-file-change', tempImageFiles.value)
    },
    fail: (err) => {
      console.error('选择图片失败:', err)
      emit('upload-error', new Error('选择图片失败'))
    }
  })
}

// 移除图片
const removeImage = (index) => {
  // 如果是云存储的图片，记录ID以便后续删除
  const removedItem = displayValues.value[index]
  
  // 从各个数组中移除
  displayValues.value.splice(index, 1)
  if (index < tempImageFiles.value.length) {
    tempImageFiles.value.splice(index, 1)
  }
  
  updateModelValue()
  emit('remove', removedItem)
}

// 更新modelValue
const updateModelValue = () => {
  const value = props.maxCount === 1 
    ? displayValues.value[0] || '' 
    : [...displayValues.value]
  emit('update:modelValue', value)
}

// 上传所有图片到云存储（Promise 版本）
const uploadImage = () => {
  return new Promise(async (resolve, reject) => {
    if (tempImageFiles.value.length === 0) {
      // 如果没有新图片，但当前值是有效的文件ID，则直接返回
      const hasValidFiles = displayValues.value.some(item => isValidFileId(item))
      if (hasValidFiles) {
        resolve(props.maxCount === 1 ? displayValues.value[0] : [...displayValues.value])
        return
      }
      resolve(props.maxCount === 1 ? '' : [])
      return
    }

    try {
      uni.showLoading({
        title: '上传图片中...',
        mask: true
      })

      const uploadedUrls = []
      
      // 上传每张新图片
      for (let i = 0; i < tempImageFiles.value.length; i++) {
        const file = tempImageFiles.value[i]
        
        // 准备云存储路径
        const date = new Date()
        const year = date.getFullYear()
        const month = date.getMonth() + 1
        const day = date.getDate()
        const cloudPath = `${props.uploadPath}/${year}/${month}/${day}/${Date.now()}_${Math.random().toString().slice(2, 7)}.webp`

        // 获取压缩后的图片路径
        let filePath = await compressImage(file.path)

        // 使用扩展存储云对象上传
        const uniCloudStorageExtCo = uniCloud.importObject("ext-storage-co")
        const uploadFileOptionsRes = await uniCloudStorageExtCo.getUploadFileOptions({
          cloudPath: cloudPath,
          domain: "cdn.isscloud.site", // 域名地址
        })

        // 执行上传
        const uploadResult = await uni.uploadFile({
          ...uploadFileOptionsRes.uploadFileOptions,
          filePath: filePath,
        })
        
        const obj = JSON.parse(uploadResult.data)
        const fileID = `qiniu://${obj.key}`
        uploadedUrls.push(fileID)
      }

      // 删除旧图片（如果是更新操作且旧图片是云存储的）
      if (_ids.value.length > 0) {
        try {
          let res = await wallpaperObj.deleteImages(_ids.value)
          console.log('旧图片删除成功', res)
        } catch (deleteErr) {
          console.error('删除旧图片失败:', deleteErr)
        }
      }

      // 更新显示值和临时文件状态
      // 保留非临时文件的URL（即之前已经上传的）
      const existingUrls = displayValues.value.slice(0, displayValues.value.length - tempImageFiles.value.length)
      displayValues.value = [...existingUrls, ...uploadedUrls]
      tempImageFiles.value = []
      
      const resultValue = props.maxCount === 1 ? displayValues.value[0] : [...displayValues.value]
      emit('update:modelValue', resultValue)
      emit('upload-success', resultValue)
      
      resolve(resultValue)
    } catch (error) {
      console.error('上传图片失败:', error)
      emit('upload-error', error)
      reject(error)
    } finally {
      uni.hideLoading()
    }
  })
}

// 判断是否为有效的文件ID
function isValidFileId(id) {
  return id && (id.startsWith('qiniu://') || id.startsWith('cloud://'))
}

// 压缩图片（保持不变）
const compressImage = async (filePath) => {
  // 判断运行环境
  if (process.env.UNI_PLATFORM === 'h5') {
    // H5环境使用Canvas压缩
    try {
      return await compressViaCanvas(filePath)
    } catch (compressErr) {
      console.warn('Canvas压缩失败，使用原图上传', compressErr)
      return filePath.replace(/\.[^/.]+$/, '') + '.webp'
    }
  } else if (uni.compressImage && typeof uni.compressImage === 'function') {
    // 小程序/App环境使用uni.compressImage
    try {
      const compressedResult = await new Promise((resolve, reject) => {
        uni.compressImage({
          src: filePath,
          quality: props.quality,
          format: 'webp',
          success: resolve,
          fail: reject
        })
      })
      return compressedResult.tempFilePath
    } catch (compressErr) {
      console.warn('图片压缩失败，使用原图上传', compressErr)
      return filePath.replace(/\.[^/.]+$/, '') + '.webp'
    }
  } else {
    console.warn('当前环境不支持压缩，使用原图上传')
    return filePath.replace(/\.[^/.]+$/, '') + '.webp'
  }
}

// H5环境专用的Canvas压缩方法（保持不变）
const compressViaCanvas = (filePath) => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.crossOrigin = 'Anonymous'
    img.src = filePath
    
    img.onload = () => {
      try {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        
        // 计算压缩后的尺寸（保持宽高比）
        let width = img.width
        let height = img.height

        if (width > props.maxSize || height > props.maxSize) {
          const ratio = Math.min(props.maxSize / width, props.maxSize / height)
          width = width * ratio
          height = height * ratio
        }

        canvas.width = width
        canvas.height = height
        ctx.drawImage(img, 0, 0, width, height)

        // 转换为WebP格式
        canvas.toBlob((blob) => {
          const compressedUrl = URL.createObjectURL(blob)
          resolve(compressedUrl)
        }, 'image/webp', props.quality / 100)
      } catch (err) {
        reject(err)
      }
    }
    
    img.onerror = (err) => {
      reject(new Error('图片加载失败'))
    }
  })
}

// 暴露上传方法给父组件
defineExpose({
  uploadImage: uploadImage,
  getTempFiles: () => tempImageFiles.value,
  getDisplayValues: () => displayValues.value
})

// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
  if (Array.isArray(newVal)) {
    if (JSON.stringify(newVal) !== JSON.stringify(displayValues.value)) {
      displayValues.value = [...newVal]
      tempImageFiles.value = []
    }
  } else if (newVal !== displayValues.value[0]) {
    displayValues.value = newVal ? [newVal] : []
    tempImageFiles.value = []
  }
}, { immediate: true, deep: true })

// 初始化
initDisplayValues()
</script>

<style lang="scss" scoped>
.image-uploader {
  width: 100%;
  
  .image-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }
  
  .upload-btn {
    width: 100px;
    height: 100px;
    border: 1px dashed #ddd;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #f8f8f8;
    
    .upload-text {
      font-size: 12px;
      color: #999;
      margin-top: 8px;
    }
  }
  
  .image-preview {
    position: relative;
    width: 100px;
    height: 100px;
    border-radius: 4px;
    overflow: hidden;
    background-color: rgba(0, 0, 0, 0.5);
    
    .preview-image {
      width: 100%;
      height: 100%;
    }
    
    .image-actions {
      position: absolute;
      top: 0;
      right: 0;
      padding: 4px;
      border-bottom-left-radius: 4px;
    }
  }
}
</style>